package tool.cfgformats;

import guru.nidi.graphviz.engine.Format;
import guru.nidi.graphviz.engine.Graphviz;
import guru.nidi.graphviz.model.Graph;
import tool.model.cfg.EntryNode;
import tool.utils.FormatResolver;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class GraphBuilder {

    public Map<String, Graph> createGraphs(List<EntryNode> cfgs) {
        System.out.println("graphviz生成cfg");
        Map<String, Graph> result = new HashMap<>();

        //每一个CFG的计算结果都存在result中
        for(EntryNode entryNode : cfgs) {
            System.out.println("节点：" + entryNode.getName());

            //每个cfg都生成图
            CfgToGraphConverter builder = new CfgToGraphConverter();
            Graph graph = builder.createGraph(entryNode);
            String entryNodeName = entryNode.getName();

            String filePath = entryNode.getFilePath();
            String cleanFileName;
            if(filePath.contains(File.separator)) {
               cleanFileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
            }
            else {
                cleanFileName = filePath;
            }
            result.put(cleanFileName + "_" +
            entryNodeName.substring(entryNodeName.indexOf("\n") + 1), graph);
        }
        return result;
    }
    
    public Graph createGraph(List<EntryNode> cfgs) {
    	CfgToGraphConverter builder = new CfgToGraphConverter();
    	return builder.createGraph(cfgs);
    }

    //输出cfg图片
    public void exportGraphs( Map<String, Graph> graphs, String pathPrefix, Format format) {
        for(Map.Entry<String, Graph> graphEntry : graphs.entrySet()) {
            exportGraph(graphEntry.getValue(), pathPrefix + File.separator + graphEntry.getKey(), format);
        }
    }

    public String exportGraph(Graph graph, String filePath, Format format) {
    	String png = filePath + FormatResolver.resolve(format);
        System.out.println("保存cfg的路径：" + png);
        try {
            Graphviz.fromGraph(graph).render(format)
                    .toFile(new File(png));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return png;
    }

}
